#pragma once

#include <iostream>
#include <string>
#include <pthread.h>
#include <sched.h>
#include <thread>

namespace Common {

// 将当前线程绑定到指定的 CPU 核心。
// core_id < 0 时当作“无操作”，仍返回 true，让调用方知道本函数不会失败。
inline auto setThreadCore(int core_id) {
  if (core_id < 0) {
    return true;
  }

  cpu_set_t cpuset;
  CPU_ZERO(&cpuset);          // 清空 CPU 集合
  CPU_SET(core_id, &cpuset);  // 在集合中添加目标核心

  // pthread_setaffinity_np: 把关键线程固定在特定 CPU 上，可以减少上下文切换、缓存抖动以及线程在不同核心之间迁移造成的延迟。
  return pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset) == 0; 
}

// 创建线程并尝试设置 CPU 亲和性，随后异步执行 func(args...)
// 返回值是动态分配的 std::thread 指针，调用方需负责 join/detach 并 delete。
template <typename Fn, typename... Args>
inline std::thread *createAndStartThread(int core_id, std::string name, Fn &&func,
                                  Args &&...args) {
  auto task = new std::thread([&]() {
    if (core_id > 0 && !setThreadCore(core_id)) {
      std::cerr << "Failed to set core affinity for " << name << " " << pthread_self() << " to " << core_id << "\n";
      exit(EXIT_FAILURE);  // ⚠️ 库代码直接 exit 破坏上层控制流，建议改为抛异常或返回错误。
    }
    std::cerr << "Set core affinity for " << name << " " << pthread_self() << " to " << core_id << "\n";

    std::forward<Fn>(func)((std::forward<Args>(args))...); // ⚠️ 在 lambda 内使用引用捕获，func/args 若为局部对象会悬垂。
  });

  using namespace std::chrono_literals;
  std::this_thread::sleep_for(1s);

  return task; // ⚠️ 返回裸指针且未 join/detach，调用方若忘记释放将泄漏线程与内存。
}

} // namespace Common